from flask import Flask
import config
from exts import db, mail, cache, csrf, avatars
from blueprints.cms import bp as cms_bp
from blueprints.front import bp as front_bp
from blueprints.user import bp as user_bp
from blueprints.media import bp as media_dp
from flask_migrate import Migrate
import commands
import hooks
import filters
import logging
from flask.logging import default_handler
from logging.handlers import RotatingFileHandler
# from bbs_celery import make_celery
from models import user, post

app = Flask(__name__)
# 选择开发环境
app.config.from_object(config.DevelopmentConfig)
# 初始化db
db.init_app(app)
# 初始化邮箱
mail.init_app(app)
# 初始化缓存
cache.init_app(app)
# 初始化生成随机头像
avatars.init_app(app)
# 构建celery
# celery = make_celery(app)
# CSRF保护
csrf.init_app(app)
# 添加钩子函数 用于注册一个在每个请求处理之前执行的函数
app.before_request(hooks.bbs_before_request)
# 3个处理错误的钩子函数
app.errorhandler(401)(hooks.bbs_401_error)
app.errorhandler(404)(hooks.bbs_404_error)
app.errorhandler(500)(hooks.bbs_500_error)
# 添加模板过滤器
app.template_filter("email_hash")(filters.email_hash)

# 注册蓝图
app.register_blueprint(cms_bp)
app.register_blueprint(front_bp)
app.register_blueprint(user_bp)
app.register_blueprint(media_dp)
# 模型映射到数据库
migrate = Migrate(app, db)
# 设置日志级别
app.logger.setLevel(logging.DEBUG)
# 日志输出到定向文件
file_handle = logging.FileHandler('pythonbbs.log', encoding="utf-8")
app.logger.addHandler(file_handle)

# commmands.py里面装饰器 - 添加命令
# 在使用 app.cli.command() 装饰器时，应该传入函数本身（不加括号）
app.cli.command("create-permission")(commands.create_permission)
app.cli.command("create-role")(commands.create_role)
# 添加创建测试用户命令
app.cli.command("create-test-front")(commands.create_test_user)
# 添加管理员
app.cli.command("create-admin")(commands.create_admin)
# 添加板块
app.cli.command("create_board")(commands.create_board)
# 添加测试帖子
app.cli.command("create-test-post")(commands.create_test_post)

# 移除Flask自带的handler
# app.logger.removeHandler(default_handler)
# 创建一个RotatingFileHandler对象
# file_handler = RotatingFileHandler("pythonbbs.log", maxBytes=16384, backupCount=20)
# 设置handler级别为DEBUG
# file_handler.setLevel(logging.DEBUG)
# 创建日志记录的格式
# file_formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(filename)s: %(lineno)d]')
# 将日志格式对象添加到handler中
# file_handler.setFormatter(file_formatter)
# 将handler添加到app.logger中
# app.logger.addHandler(file_handler)

if __name__ == '__main__':
    app.run()
